package com.central.cms.admin.config.spring;

import com.alibaba.fastjson.JSON;
import com.central.cms.commons.base.response.ObjectResult;
import com.central.cms.commons.base.response.Result;
import com.central.cms.commons.util.ControllerUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component("userDetailsServiceImpl")
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements UserDetailsService{

    private static final String[] EXCLUDE_LIST = {
            "/**/*.js","/**/*.json",
            "/**/*.css","/**/*.png",
            "/**/*.jpg","/**/*.gif",
            "/**/*.woff2","/**//**/*.woff2",
            "/**/*.svg","/**/**/*.svg",
            "/**/*.ttf","/**/*.eot","/**/*.map"
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
                http.csrf().disable()
                .authorizeRequests()
                .antMatchers(EXCLUDE_LIST).permitAll()
                .anyRequest().authenticated()  // 所有请求需要身份认证
                .and()
                .formLogin()
                .loginPage("/login")
                .failureHandler(loginFailureHandler())
                .successHandler(loginSuccessHandler())
                .permitAll()
                .and()
                .rememberMe()
                .rememberMeParameter("rememberMe")
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login")
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .userDetailsService(this::loadUserByUsername)
                .passwordEncoder(passwordEncoder());
    }


    @Bean
    @DependsOn("userDetailsServiceImpl")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationSuccessHandler loginSuccessHandler(){
        return (request, response, authentication) -> {
            if(ControllerUtil.isAjax(request)){
                Result result = ObjectResult.success("登陆成功！");
                ControllerUtil.renderJson(JSON.toJSONString(result));
            }else {
                response.sendRedirect("/dashboard");
            }
        };
    }

    @Bean
    public AuthenticationFailureHandler loginFailureHandler(){
        return (request, response, e) -> {
            if(ControllerUtil.isAjax(request)){
                Result result = ObjectResult.error();
                result.setMessage(e.getMessage());
                ControllerUtil.renderJson(JSON.toJSONString(result));
            }else {
                response.sendRedirect("/login");
            }
        };
    }

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        List list = new ArrayList();
        list.add(new SimpleGrantedAuthority("1"));
        list.add(new SimpleGrantedAuthority("2"));
        list.add(new SimpleGrantedAuthority("3"));
        list.add(new SimpleGrantedAuthority("4"));
        return new User("123",passwordEncoder().encode("123") , list);
    }
}
